BITS 16

%include "macrosmodoreal.mac"

%define KORG 0x1200

global start
extern tsss
extern gdt
extern GDT_DESC
extern IDT_DESC
extern inicializar_idt

extern inicializar_dir_kernel
extern inicializar_dir_usuario
extern inicializar_mmu
extern mapear_pagina
extern unmapear_pagina
extern pagina_libre_kernel 


extern resetear_pic
extern habilitar_pic

;Aca arranca todo, en el primer byte.
start:
		cli			;no me interrumpan por ahora
		jmp 	bienvenida

;aca ponemos todos los mensajes		
iniciando: db 'Iniciando el kernel del TP'
iniciando_len equ $ - iniciando		


bienvenida:

		IMPRIMIR_MODO_REAL iniciando, iniciando_len, 0x07, 0, 0
		
		;Habilitar A20
		call	checkear_A20
		call 	habilitar_A20
		call	checkear_A20
		
		;xchg bx, bx 
		
		;
		; Ejercicio 1:
		
		; - Completar GDT
		LGDT[GDT_DESC]
		; - Pasar a MP
		MOV EAX, CR0
		OR EAX, 1
		MOV CR0, EAX
		JMP 0x08:modoprotegido
		
		
		BITS 32
modoprotegido:
		
		MOV AX, 0x10
		MOV DS, AX
		MOV ES, AX
		MOV GS, AX
		MOV FS, AX
		MOV SS, AX
		MOV esp, 0x00019000
	
		MOV AX, 0x18; seteamos el segmento de video (4to índice empezando por el 1)
		MOV ES, AX

		
		; - Pintar pantalla de negro y hacer recuadro

		;Limplio la pantalla
		xor esi,esi
		mov ecx,(80*25)
		mov ax,0
cicloLimpio:
			mov [es:esi],ax
			add esi,2
		loop cicloLimpio
		
		
		;Escribo la primer linea en la 3er fila
		mov esi,(80*2*2)	;La posicion en la matriz pantalla es en bytes
		mov ecx,80		;Como escribo de a 2 bytes necesito 80 iteraciones para completar la linea
		mov ax,0x7000;RGB todos en 1 para el fondo
		cicloFila1:
			mov [es:esi],ax
			add esi,2
		loop cicloFila1
		
		;Escribo la 2da linea en la 24ra fila
		mov esi,(80*2*23);La posicion en la matriz pantalla es en bytes
		mov ecx,80;Como escribo de a 2 bytes necesito 80 iteraciones para completar la linea
		mov ax,0x7000;RGB todos en 1 para el fondo
		cicloFila2:
			mov [es:esi],ax
			add esi,2
		loop cicloFila2
		
		
		; Ejercicio 2
		; - crear idt para excepciones
		LIDT[IDT_DESC]
		call inicializar_idt
		; - generar excepcion
		;STI
		
		;mov bx,0	;division por cero
		;div bx
		
		; Ejercicio 3
		; - inicializar la mmu
		call inicializar_mmu	

		; - inicializar el directorio de paginas del kernel h 4mb
		call inicializar_dir_kernel

		
		; - habilitar paginacion				
		;xchg bx,bx		
		mov cr3,eax		;direccion del dir de pags.
	
	
		;Activamos paginacion
		
		mov eax,cr0
		or eax,0x80000000
		mov cr0,eax
		
		; - imprimir mensaje
		
		MOV ECX, mensaje_len
		MOV ESI, mensaje
		xor edi,edi

		ADD EDI, 110			;Margen en pantalla
		MOV AH, 0x03
		cicloPaginas:
			LODSB
			STOSW
			LOOP cicloPaginas
		
		
		; - habilitar paginas de 4 mb
		mov eax,cr4
		or eax,0x00000010		; seteamos en 1 el bit 4 (El 5to bit)
		mov cr4,eax
		
		; - modificar el directorio de p'aginas para mapear h 64mb usando paginas de 4mb
		; - TODO: ALGO PARA PROBAR QUE ANDA
		
		
		; Ejercicio 4:
		; - inicializar_dir_usuario
	
		call inicializar_dir_usuario
		mov ebx,eax			; en ebx guardamos el cr3 del usuario
		
		; - mapear_pagina
		push dword 0x00000003		; atributos, lect-esc, presente, supervisor
		push dword 0x000B8000		; dirección real
		push ebx			; cr3 del usuario
		push dword 0x1F040000		; direccion virtual
		call mapear_pagina
		add esp,16			

		; - intercambiar dir		
		mov eax,cr3
		mov edx,eax			; en edx guardamos el cr3 del kernel
		
		mov eax,ebx			
		mov cr3,eax			; apuntamos el cr3 al dir del usuario
		
		
		; - pintar primer linea		
		mov esi, 0x1F040000		;La pantalla esta mapeada a esta dir.
		mov ecx,80
		
		cicloPrimeraFila:
			mov ax,[ds:esi]
			and ah,0x8f		; ponemos a 0 el rgb del fondo
			or ah,0x40		; ponemos en rojo el rgb del fondo
			mov [ds:esi],ax
			add esi,2
		loop cicloPrimeraFila
		
		; - volver a intercambiar
		mov eax, edx
		mov cr3, eax			; cr3 apunta nuevamente al cr3 del kernel
		
		; - unmapear
		push dword ebx			; pusheamos el cr3 del usuario
		push dword 0x1F040000		; desmapeamos esta direccion.
		call unmapear_pagina
		add esp,8
		
		;;;; solo para ver si funciono el desmapeo (No se pide esta parte).
		;;;;mov eax,ebx
		;;;;mov cr3,eax
		;;;;xchg bx,bx		
		
		
		; Ejercicio 5
		; - completar IDT 88 y 89
		; - completar IDT reloj y teclado
		; - habilitar pic e interrupciones para probar.
		call resetear_pic
		call habilitar_pic
		sti
		; Prueba de interrupciones 88/89
		;int 88
		;xchg bx,bx
		;mov eax,0xFFFFFFFF
		;xchg bx,bx
		;int 89
		;xchg bx,bx
		
		; Ejercicio 6
		; - cargar_tarea
		; - saltar a la tarea 1
		; - modificar ISR reloj para que cambie de tarea
		
		jmp	$
		
%include "a20.asm"

mensaje: db "Led Zeppelin."
mensaje_len equ $-mensaje

TIMES 0x2000 - KORG - ($ - $$) db 0x0
